import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

/**
 * 复制工作者
 *
 * @Author: 贺坤
 * @Date: 2021/5/20 8:56
 */
public class CopyWorker extends SwingWorker<Integer, Integer> {

    private JTextArea status;
    private File srcDir;
    private File targetDir;

    /**
     * @param status 文本
     */
    CopyWorker(JTextArea status) {
        this.status = status;
    }

    @Override
    protected Integer doInBackground() throws Exception {
        if (srcDir == null) {
            status.setText("请选源路径");
            return 0;
        }

        if (targetDir == null) {
            status.setText("请选目标路径");
            return 0;
        }
        Count count = new Count(0);
        // 判断源 是文件还是目录
        if (srcDir.isDirectory()) {
            int txtFilesCount = getTxtFilesCount(srcDir);
            count.setTxtFilesCount(txtFilesCount);
            fileContentsCopy(srcDir, targetDir, count);
        } else {
            count.setTxtFilesCount(1);
            fileCopy(srcDir, new File(targetDir, srcDir.getName()), count);

        }
        status.insert("完成!! 谢谢使用", 0);
        return count.getCount();
    }

    public static int getTxtFilesCount(File srcFile) {
        int count = 0;
        // 把所有目录、文件放入数组
        File[] files = srcFile.listFiles();
        // 遍历数组每一个元素
        for (File f : files) {
            // 判断元素是不是文件夹，是文件夹就重复调用此方法（递归）
            if (f.isDirectory()) {
                count += getTxtFilesCount(f);
            } else {
                count++;
            }
        }
        // 返回.txt文件个数
        return count;
    }

    /**
     * 文件复制
     */
    private void fileCopy(File srcDir, File targetDir, Count count) {
        try {

            FileInputStream inputStream = new FileInputStream(srcDir);
            FileChannel inputStreamChannel = inputStream.getChannel();
            FileOutputStream outputStream = new FileOutputStream(targetDir, true);
            FileChannel outputStreamChannel = outputStream.getChannel();
            inputStreamChannel.transferTo(0, inputStreamChannel.size(), outputStreamChannel);
            outputStreamChannel.close();
            outputStream.close();
            inputStreamChannel.close();
            inputStream.close();

            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(count.getProgress());
            stringBuilder.append(" >> ");
            stringBuilder.append(srcDir.getCanonicalPath());
            stringBuilder.append("\r\n");
            status.insert(stringBuilder.toString(), 0);

        } catch (IOException e) {
            e.printStackTrace();
            System.out.println(e);
        }
    }

    /**
     * 复制文件夹,如果文件夹存在就创建
     *
     * @param srcDir
     * @param targetRootDir 目标的跟目录
     */
    private void fileContentsCopy(File srcDir, File targetRootDir, Count count) {
        // 文件复制路径
        File targetCopyDir = new File(targetRootDir, srcDir.getName());
        // 当目标路径为没有文件夹的的时候,创建文件夹
        if (!targetCopyDir.exists()) {
            targetCopyDir.mkdirs();
        }
        File[] files = srcDir.listFiles();
        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            if (file.isDirectory()) {
                fileContentsCopy(file, targetCopyDir, count);
            } else {
                fileCopy(file, new File(targetCopyDir, file.getName()), count);
            }
        }

    }

    public void copyInit(File srcDir, File targetDir) {
        this.srcDir = srcDir;
        this.targetDir = targetDir;
    }
}